#include <SPI.h>
#include <LoRa.h>
#include <Wire.h>
#include <Ethernet.h>
#include "lora_com.h"
#include "ai_analyzer.h"

// 定义引脚
#define LORA_SS 10
#define LORA_RST 9
#define LORA_DIO0 3

// 以太网参数（根据实际硬件配置）
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetClient client;

// 服务器信息
char server[] = "192.168.1.100";
int serverPort = 8080;

// 设备ID
const uint8_t gatewayId = 0xFF; // 网关使用特殊ID

// 初始化LoRa通信模块
LoRaCom loraCom(LORA_SS, LORA_RST, LORA_DIO0, gatewayId);

// 初始化AI分析器（用于网关节点的数据分析）
AIAnalyzer aiAnalyzer;

// 数据缓冲区
#define MAX_NODES 10
#define DATA_BUFFER_SIZE 50
SensorData nodeData[MAX_NODES][DATA_BUFFER_SIZE];
int nodeDataIndex[MAX_NODES] = {0};

void setup() {
  // 初始化串口通信
  Serial.begin(115200);
  while (!Serial) {
    ; // 等待串口连接
  }
  
  Serial.println("智能传感器网络 - 网关节点");
  
  // 初始化LoRa模块
  if (!loraCom.begin()) {
    Serial.println("LoRa模块初始化失败！");
    while (1);
  }
  Serial.println("LoRa模块初始化成功");
  
  // 初始化AI分析器
  aiAnalyzer.init();
  
  // 初始化以太网连接
  if (Ethernet.begin(mac) == 0) {
    Serial.println("无法获取IP地址，使用静态IP");
    Ethernet.begin(mac, ip);
  }
  delay(1000);
  Serial.print("以太网IP地址: ");
  Serial.println(Ethernet.localIP());
  
  // 初始化节点数据缓冲区
  for (int i = 0; i < MAX_NODES; i++) {
    for (int j = 0; j < DATA_BUFFER_SIZE; j++) {
      nodeData[i][j].nodeId = i;
      nodeData[i][j].temperature = 0;
      nodeData[i][j].humidity = 0;
      nodeData[i][j].light = 0;
    }
  }
}

void loop() {
  // 接收传感器节点数据
  receiveSensorData();
  
  // 发送数据到服务器
  sendDataToServer();
  
  // 处理来自服务器的命令
  processServerCommands();
  
  // 短暂延迟
  delay(100);
}

void receiveSensorData() {
  // 缓冲区用于接收数据
  uint8_t buffer[255];
  uint8_t senderId;
  uint8_t messageType;
  
  // 接收消息
  int payloadLength = loraCom.receiveMessage(buffer, sizeof(buffer), senderId, messageType);
  
  if (payloadLength > 0) {
    if (messageType == SENSOR_DATA) {
      // 处理传感器数据
      SensorData data;
      memcpy(&data, buffer, sizeof(SensorData));
      
      // 检查节点ID是否有效
      if (data.nodeId > 0 && data.nodeId < MAX_NODES) {
        // 存储数据到缓冲区
        nodeData[data.nodeId][nodeDataIndex[data.nodeId]] = data;
        nodeDataIndex[data.nodeId] = (nodeDataIndex[data.nodeId] + 1) % DATA_BUFFER_SIZE;
        
        // 显示接收到的数据
        Serial.print("接收到节点 ");
        Serial.print(data.nodeId);
        Serial.print(" 数据: 温度=");
        Serial.print(data.temperature);
        Serial.print("°C, 湿度=");
        Serial.print(data.humidity);
        Serial.print("%, 光照=");
        Serial.print(data.light);
        Serial.println("lx");
        
        // 使用AI分析器检测异常
        int anomaly = aiAnalyzer.detectAnomaly(data);
        if (anomaly != 0) {
          Serial.print("检测到异常: 节点 ");
          Serial.print(data.nodeId);
          Serial.print(", 代码=");
          Serial.println(anomaly, HEX);
          
          // 如果检测到异常，立即发送到服务器
          sendAnomalyAlert(data, anomaly);
        }
        
        // 发送确认消息
        loraCom.sendAck(data.nodeId, SENSOR_DATA, 1); // 1表示成功接收
      }
    }
    else if (messageType == STATUS) {
      // 处理状态消息
      Serial.print("接收到节点 ");
      Serial.print(senderId);
      Serial.print(" 状态消息: ");
      for (int i = 0; i < payloadLength; i++) {
        Serial.print(buffer[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
  }
}

void sendDataToServer() {
  // 每30秒发送一次数据到服务器
  static unsigned long lastSendTime = 0;
  unsigned long currentTime = millis();
  
  if (currentTime - lastSendTime >= 30000) {
    lastSendTime = currentTime;
    
    // 连接到服务器
    if (client.connect(server, serverPort)) {
      Serial.println("连接到服务器成功");
      
      // 发送HTTP请求头
      client.println("POST /api/data HTTP/1.1");
      client.print("Host: ");
      client.println(server);
      client.println("Content-Type: application/json");
      
      // 构建JSON数据
      String jsonData = "{\"gatewayId\": " + String(gatewayId) + ", \"timestamp\": " + String(currentTime) + ", \"nodes\": [";
      
      bool firstNode = true;
      for (int i = 1; i < MAX_NODES; i++) {
        if (nodeDataIndex[i] > 0) {
          // 获取最新数据
          int latestIndex = (nodeDataIndex[i] - 1 + DATA_BUFFER_SIZE) % DATA_BUFFER_SIZE;
          SensorData data = nodeData[i][latestIndex];
          
          if (!firstNode) {
            jsonData += ",";
          }
          firstNode = false;
          
          jsonData += "{";
          jsonData += "\"nodeId\": " + String(data.nodeId) + ",";
          jsonData += "\"temperature\": " + String(data.temperature) + ",";
          jsonData += "\"humidity\": " + String(data.humidity) + ",";
          jsonData += "\"light\": " + String(data.light);
          jsonData += "}";
        }
      }
      
      jsonData += "]}";
      
      // 发送内容长度和数据
      client.print("Content-Length: ");
      client.println(jsonData.length());
      client.println();
      client.println(jsonData);
      
      // 等待服务器响应
      delay(100);
      while (client.available()) {
        String line = client.readStringUntil('\r');
        Serial.print(line);
      }
      
      // 断开连接
      client.stop();
      Serial.println("数据发送完成");
    } else {
      Serial.println("连接到服务器失败");
    }
  }
}

void sendAnomalyAlert(SensorData data, int anomaly) {
  // 连接到服务器
  if (client.connect(server, serverPort)) {
    Serial.println("发送异常警报到服务器");
    
    // 发送HTTP请求头
    client.println("POST /api/anomaly HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Content-Type: application/json");
    
    // 构建JSON数据
    String jsonData = "{";
    jsonData += "\"gatewayId\": " + String(gatewayId) + ",";
    jsonData += "\"nodeId\": " + String(data.nodeId) + ",";
    jsonData += "\"timestamp\": " + String(millis()) + ",";
    jsonData += "\"temperature\": " + String(data.temperature) + ",";
    jsonData += "\"humidity\": " + String(data.humidity) + ",";
    jsonData += "\"light\": " + String(data.light) + ",";
    jsonData += "\"anomalyCode\": " + String(anomaly);
    jsonData += "}";
    
    // 发送内容长度和数据
    client.print("Content-Length: ");
    client.println(jsonData.length());
    client.println();
    client.println(jsonData);
    
    // 断开连接
    delay(100);
    client.stop();
  }
}

void processServerCommands() {
  // 检查是否有来自服务器的连接
  EthernetClient client = Ethernet.serverAvailable();
  if (client) {
    Serial.println("接收到服务器连接");
    
    // 读取请求
    String request = "";
    while (client.available()) {
      char c = client.read();
      request += c;
    }
    
    // 简单解析请求
    if (request.indexOf("POST /api/command") >= 0) {
      // 这里应该解析JSON命令
      Serial.println("接收到命令请求");
      
      // 示例：解析节点ID和命令类型
      int nodeId = parseNodeIdFromRequest(request);
      String command = parseCommandFromRequest(request);
      
      if (nodeId > 0 && nodeId < MAX_NODES) {
        // 发送命令到传感器节点
        sendCommandToNode(nodeId, command);
        
        // 发送响应
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: application/json");
        client.println();
        client.println("{\"status\": \"success\", \"message\": \"命令已发送\"}");
      } else {
        client.println("HTTP/1.1 400 Bad Request");
        client.println("Content-Type: application/json");
        client.println();
        client.println("{\"status\": \"error\", \"message\": \"无效的节点ID\"}");
      }
    } else {
      // 返回404响应
      client.println("HTTP/1.1 404 Not Found");
      client.println();
    }
    
    // 断开连接
    delay(1);
    client.stop();
  }
}

void sendCommandToNode(uint8_t nodeId, String command) {
  // 发送命令到指定节点
  int result = loraCom.sendText(nodeId, command.c_str());
  
  if (result > 0) {
    Serial.print("命令已发送到节点 ");
    Serial.print(nodeId);
    Serial.print(": ");
    Serial.println(command);
  } else {
    Serial.print("发送命令到节点 ");
    Serial.print(nodeId);
    Serial.println(" 失败");
  }
}

int parseNodeIdFromRequest(String request) {
  // 简单的解析函数，实际应用中应该使用JSON解析库
  int start = request.indexOf("nodeId") + 8;
  int end = request.indexOf(",", start);
  if (start > 8 && end > start) {
    String nodeIdStr = request.substring(start, end);
    return nodeIdStr.toInt();
  }
  return -1;
}

String parseCommandFromRequest(String request) {
  // 简单的解析函数，实际应用中应该使用JSON解析库
  int start = request.indexOf("command") + 10;
  int end = request.indexOf("\",", start);
  if (start > 10 && end > start) {
    return request.substring(start, end);
  }
  return "";
}